﻿namespace com.game.module.fight.arpg
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;

    public abstract class Shape : MonoBehaviour
    {
        private GameObject _go;
        private static List<Shape> _list = new List<Shape>();
        protected Mesh _mesh;
        protected MeshFilter _meshFilter;
        protected MeshRenderer _meshRender;
        private static int _prevUpdateFrame;
        protected int[] _triangles;
        protected Vector2[] _uvs;
        protected Vector3[] _vertices;

        protected Shape()
        {
        }

        public T AddComp<T>() where T: Component
        {
            T component = base.GetComponent<T>();
            if (null == component)
            {
                component = this.AddComp<T>();
            }
            return component;
        }

        protected abstract void CreateIB();
        protected abstract void CreateVB();
        public void Move(float x, float y, float z)
        {
            Transform transform = base.transform;
            Vector3 localPosition = transform.localPosition;
            localPosition.x = x;
            localPosition.y = y;
            localPosition.z = z;
            transform.localPosition = localPosition;
        }

        private void OnDisable()
        {
            _list.Remove(this);
        }

        private void OnEnable()
        {
            _list.Add(this);
            if (null == this._meshFilter)
            {
                this._meshFilter = this.AddComp<MeshFilter>();
            }
            if (null == this._meshRender)
            {
                this._meshRender = this.AddComp<MeshRenderer>();
            }
            if (null == this._mesh)
            {
                this._mesh = (null != this._meshFilter) ? this._meshFilter.mesh : null;
            }
        }

        public static void ReDraw()
        {
            if ((_list != null) && ((Time.frameCount - _prevUpdateFrame) >= 4))
            {
                _prevUpdateFrame = Time.frameCount;
                int count = _list.Count;
                for (int i = 0; i < count; i++)
                {
                    _list[i].SelfUpdate();
                }
            }
        }

        private void SelfUpdate()
        {
            if ((null != this._mesh) && this.freshMesh)
            {
                this.UpdateMesh();
            }
        }

        private void Update()
        {
            ReDraw();
        }

        protected void UpdateMesh()
        {
            if (null != this._mesh)
            {
                this._mesh.Clear();
                this.CreateVB();
                this.CreateIB();
                this._mesh.vertices = this._vertices;
                this._mesh.uv = this._uvs;
                this._mesh.triangles = this._triangles;
            }
        }

        protected virtual bool freshMesh
        {
            get
            {
                return false;
            }
        }

        public GameObject go
        {
            get
            {
                if (null == this._go)
                {
                    this._go = base.gameObject;
                }
                return this._go;
            }
        }

        public virtual ShapeType shapeType
        {
            get
            {
                return ShapeType.NONE;
            }
        }
    }
}

